package se.webbzon.boltzmann.minigame.botany;

import java.awt.Image;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;

import se.webbzon.boltzmann.minigame.sandbox.SandBox;
import se.webbzon.boltzmann.minigame.sandbox.SandBoxObject;
import se.webbzon.oschi01.resourceset.ResourceSet;
import se.webbzon.oschi01.worldarea.WorldArea;
import se.webbzon.oschi01.worldcamera.WorldCameraPane;
import se.webbzon.oschi01.worldobject.WorldObject;

public abstract class AbstractMolecule extends SandBoxObject {
	
	// The 2-dimensional depth of the cell
	private static final int depth = 2;
	
	private static final double maxRotationSpeed = 0.02;
	private static final double maxSpeed = 0.4;
	
	// The rectangular dimension of the sand box
	private final Rectangle d;
	
	// The rotation of the molecule
	private double theta, w;
	
	// The velocity of the molecule
	private double vx, vy;
	
	/*============================================================
	Constructors
	============================================================*/

	public AbstractMolecule() {
		super(WorldObject.onStep + WorldObject.onPostDraw, depth);
		d = new Rectangle();
		setSize(16,16);
		theta = 2 * Math.PI * Math.random();
		drop();
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	public void setSize(double width, double height) {
		super.setSize(width, height);
	}
	
	public double getXVelocity() {
		return vx;
	}
	
	public double getYVelocity() {
		return vy;
	}
	
	public void grab() {
		vx = vy = w = 0;
	}
	
	public void drop() {
		w = maxRotationSpeed * (2 * Math.random() - 1);
		vx = maxSpeed * (2 * Math.random() - 1);
		vy = maxSpeed * (2 * Math.random() - 1);
	}
	
	@Override public void onAttach(SandBox box) {
		box.getBoundary(d);
	}

	@Override public void onDetach(SandBox box) {};
	
	@Override public void onStep(WorldArea world) {
		theta += w;
		if (theta > 2 * Math.PI)
			theta -= 2 * Math.PI;
		else if (theta < - 2 * Math.PI)
			theta += 2 * Math.PI;
		
		if (getX() + getXVelocity() > d.getWidth() || getX() + getXVelocity() < 0)
			vx = -vx;
		if (getY() + getYVelocity() > d.getHeight() || getY() + getYVelocity() < 0)
			vy = -vy;
		setPosition(getX() + getXVelocity(), getY() + getYVelocity());
	}

	@Override public void onPostDraw(WorldArea world, WorldCameraPane hud) {
		AffineTransform trans = new AffineTransform();
		trans.translate(getX(), getY());
		trans.rotate(theta);
		int w = (int) getWidth();
		int h = (int) getWidth();
		hud.setTransform(trans);
		hud.drawImage(getImage().get(0), -w/2, -h/2, w, h);
		hud.resetTransform();
	}
	
	/*============================================================
	Protected Methods
	============================================================*/
	
	/** Returns the resource set containing the image of the molecule. **/
	protected abstract ResourceSet<Image> getImage();

}
